package com.kayang.webapi.controller;


import com.kayang.common.core.UserContext;
import com.kayang.common.exception.OtherException;
import com.kayang.common.misc.WebHelper;
import com.kayang.webapi.entity.WebAPILog;
import com.kayang.webapi.event.Event;
import com.kayang.nadapt.util.*;
import com.kayang.webapi.service.DataBizService;
import com.kayang.webapi.service.DataService;
import com.kayang.webapi.tool.MsgCode;
import com.kayang.webapi.tool.MsgContent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


@RestController
@RequestMapping(value = "/Data")
public class DataController {

    @Autowired
    DataService dataService;

    @Autowired
    DataBizService dataBizService;


    @ModelAttribute
    public void checkAll(HttpServletRequest req, ModelAndView mav) {
        HashMapIgnoreCase<Object> param = new HashMapIgnoreCase();
        //处理json报文
        try {
            InputStreamReader is = new InputStreamReader(req.getInputStream());
            BufferedReader reader = new BufferedReader(is);
            String str = "";
            String wholeStr = "";
            //一行一行读取body体
            while ((str = reader.readLine()) != null) {
                wholeStr += str;
            }
            //json转map
            Map<String, Object> _map = JsonConvert.deserializeMap(wholeStr);
            Set<String> oldKeySet = _map.keySet();
            for (String oldKey : oldKeySet) {
                param.put(oldKey, _map.get(oldKey));
            }
            is.close();
        } catch (IOException e) {
           LogHelper.error(e);
        }
        mav.getModel().putAll(param);
        if (param.get("paras") != null) {
            mav.getModel().put("PARAS", dataService.buildMapIgnoreCase((Map<String, Object>) param.get("paras")));
        }
        if (param.get("bizData") != null) {
            Object bizDataList = ((List<Map>) param.get("bizdata")).stream().map(e ->
                    dataService.buildMapIgnoreCase(e)
            ).collect(Collectors.toList());
            mav.getModel().put("BIZDATA", bizDataList);
        }

        UserContext uc = (UserContext) req.getAttribute("UserContext");
        mav.getModel().put("UC", uc);

        dataService.checkIP(param, req, uc.getUserID());

        dataService.checkParams(param, req);
    }


    //默认接口
    @PostMapping(value="/api/{cmd}")
    public ResponseEntity defaultCMD(ModelAndView mav, HttpServletRequest req, @PathVariable String cmd){
        Map<String, Object> map = mav.getModel();
        UserContext uc = (UserContext) map.get("UC");
        Map<String, Object> paras = (Map<String, Object>) map.get("PARAS");





        return ResponseEntity.ok(null);
    }


    /**
     * 从嘉扬系统里获取数据到外部系统 GetData
     */
    @PostMapping(value = "/GetData")
    public String GetData(ModelAndView mav, HttpServletRequest req) {
        Map<String, Object> map = mav.getModel();
        String json = "", msg = "", methodName = "GetData";
        String curIP = WebHelper.getClientIP(req);
        LogHelper.info("getdata req  ip " + curIP);

        UserContext uc = (UserContext) map.get("UC");
        Map<String, Object> paras = (Map<String, Object>) map.get("PARAS");
        String funcId = map.get("FUNCID").toString();

        try {
            msg = dataBizService.getDataByFormat(funcId, map.get("DATAFORMAT"), map.get("DATAPART"), paras, uc, json);
        } catch (Exception e) {
            throw new OtherException(MsgCode.Code4010, MsgContent.MsgGetDataEx);
        }
        Event.getUnique().exec(Event.getUnique().getAfterGetData(), req, map, uc);
        return msg;
    }

    /**
     * 将外部数据写入到嘉扬系统前的准备工作
     */
    @PostMapping(value = "/PutStart")

    public String PutStart(ModelAndView mav, HttpServletRequest req) {
        Map<String, Object> map = mav.getModel();
        String json = "";
        String methodName = "PutStart";
        String msg = "";
        String key = "";
        String curIP = WebHelper.getClientIP(req);
        LogHelper.info("putstart req  ip " + curIP);
        UserContext uc = null;
        try {

            json = JsonConvert.serializeObject(map);
            uc = (UserContext) map.get("UC");
        } catch (Exception e) {
            msg = dataBizService.putPrepareEx(map, json, uc, methodName, e, "");
            return msg;
        }

        Map<String, Object> paras = (Map<String, Object>) map.get("PARAS");
        try {
            String funcId = map.get("FUNCID").toString();
            msg = dataBizService.createDataPrepare(funcId, paras, uc, json);
        } catch (Exception e) {
            msg = dataBizService.putPrepareEx(map, json, uc, methodName, e, "CreateDataPrepare 方法出现异常");
            return msg;
        }
        Event.getUnique().exec(Event.getUnique().getAfterPutStart(), req, map, uc);
        return msg;

    }

    /**
     * 将外部数据写入到嘉扬系统里
     */
    @PostMapping(value = "/PutData")
    public String PutData(ModelAndView mav, HttpServletRequest req) {
        UserContext uc = new UserContext();
        Map<String, Object> map = mav.getModel();
        String json = "";
        String methodName = "PutData";
        String msg = "";
        String key = "";
        //String curIP = req.getRemoteAddr();
        String curIP = WebHelper.getClientIP(req);
        try {

            json = JsonConvert.serializeObject(map);
            WebAPILog log = new WebAPILog();
            log.setOpdata(json);
            dataBizService.writeLog2DB(log);
            uc = (UserContext) map.get("UC");
        } catch (Exception ex) {
            msg = dataBizService.putDataEx(map, json, uc, methodName, ex, "获取参数出现异常");
            return msg;
        }


        List<Map<String, Object>> bizdata = (List<Map<String, Object>>) map.get("BIZDATA");
        Map<String, Object> paras = (Map<String, Object>) map.get("PARAS");
        try {
            String funcId = map.get("FUNCID").toString();
            msg = dataBizService.createData(funcId, paras, bizdata, uc, json);
        } catch (Exception e) {
            msg = dataBizService.putDataEx(map, json, uc, methodName, e, "CreateData方法 写入数据出现异常");
            return msg;
        }
        Event.getUnique().exec(Event.getUnique().getAfterPutData(), req, map, uc);

        return msg;
    }

    /**
     * 通过SP将外部数据写入到嘉扬系统里
     */
    @PostMapping(value = "/PutDataBySP")
    public String PutDataBySP(ModelAndView mav, HttpServletRequest req) {
        UserContext uc = null;
        Map<String, Object> map = mav.getModel();
        String json = "";
        String methodName = "PutDataBySP";
        String msg = "";
        try {
            json = JsonConvert.serializeObject(map);
            WebAPILog log = new WebAPILog();
            log.setOpdata(json);
            dataBizService.writeLog2DB(log);
            uc = (UserContext) map.get("UC");
        } catch (Exception ex) {
            msg = dataBizService.putDataEx(map, json, uc, methodName, ex, "获取参数出现异常");
            return msg;
        }

        List<Map<String, Object>> bizdata = (List<Map<String, Object>>) map.get("BIZDATA");
        Map<String, Object> paras = (Map<String, Object>) map.get("PARAS");
        try {
            String funcId = map.get("FUNCID").toString();
            msg = dataBizService.createData(funcId, paras, bizdata, uc, json, true);

        } catch (Exception e) {
            msg = dataBizService.putDataEx(map, json, uc, methodName, e, "CreateData方法 写入数据出现异常");
            return msg;
        }
        return msg;
    }

    /**
     * 将外部数据写入到嘉扬系统之后的清理工作
     */
    @PostMapping(value = "/PutClose")
    public String PutClose(ModelAndView mav, HttpServletRequest req) {
        UserContext uc = new UserContext();
        Map<String, Object> map = mav.getModel();
        String json = "";
        String methodName = "PutClose";
        String msg = "";
        String key = "";
        //String curIP = req.getRemoteAddr();
        String curIP = WebHelper.getClientIP(req);
        try {
            json = JsonConvert.serializeObject(map);
            uc = (UserContext) map.get("UC");
        } catch (Exception ex) {
            msg = dataBizService.putEndEx(map, json, uc, methodName, ex, "参数获取发生异常");
            return msg;
        }

        Map<String, Object> paras = (Map<String, Object>) map.get("PARAS");
        try {

            String funcId = map.get("FUNCID").toString();
            msg = dataBizService.createDataEnd(funcId, paras, uc, json);
        } catch (Exception e) {
            msg = dataBizService.putEndEx(map, json, uc, methodName, e, "CreateDataEnd方法  写入数据清理工作出现异常");
            return msg;
        }
        Event.getUnique().exec(Event.getUnique().getAfterPutData(), req, map, uc);
        return msg;

    }

    @PostMapping(value = "/PutFile")
    // FIXME
    public String PutFile(ModelAndView mv, HttpServletRequest request) throws IOException {
        Map<String, Object> parMap = mv.getModel();
        UserContext uc = (UserContext) parMap.get("UC");
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        Map<String, Object> param = new HashMap<>();
        for (Map.Entry e : request.getParameterMap().entrySet()) {
            String k = e.getKey().toString();
            param.put(k, request.getParameter(k));
        }
        if (multipartResolver.isMultipart(request)) {
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            Iterator<String> iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                MultipartFile file = multiRequest.getFile(iter.next().toString());
                if (file != null) {
                    param.put(file.getName(), file.getBytes());
                }
            }
        }

        Map<String, Object> map = new HashMap<String, Object>();
        List<Map<String, Object>> bizdataList = new ArrayList<>();
        map.put("ACCESSTOKEN", param.get("ACCESSTOKEN"));
        map.put("PARAS", new HashMap<String, Object>());
        map.put("FUNCID", param.get("FUNCID"));
        param.remove("ACCESSTOKEN");
        param.remove("FUNCID");
        bizdataList.add(param);
        map.put("BIZDATA", bizdataList);
        String json = "";
        json = JsonConvert.serializeObject(request.getParameterMap());
        String methodName = "PutBinary";
        String msg = "";

        String curIP = request.getRemoteAddr();


        String date = "";
        Date lastTime = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<Map<String, Object>> bizdata = (List<Map<String, Object>>) map.get("BIZDATA");

        Map<String, Object> paras = (Map<String, Object>) map.get("PARAS");
        try {
            String funcId = map.get("FUNCID").toString();
            msg = dataBizService.createData(funcId, paras, bizdata, uc, json);
            return msg;
        } catch (Exception e) {
            msg = dataBizService.putDataEx(map, json, uc, methodName, e, "CreateData方法 写入数据出现异常");
            return msg;
        }

    }


    /**
     * 从嘉扬系统里获取文件到外部系统 GetFile
     */
    @PostMapping(value = "/GetFile")
    public String getFile(ModelAndView mav, HttpServletRequest req) {

        Map<String, Object> map = mav.getModel();
        String json = "", msg = "", methodName = "GetData";
        String curIP = WebHelper.getClientIP(req);
        LogHelper.info("getdata req  ip " + curIP);

        json = JsonConvert.serializeObject(map);
        UserContext uc = (UserContext) map.get("UC");
        Map<String, Object> paras = (Map<String, Object>) map.get("PARAS");
        String funcId = map.get("FUNCID").toString();
        try {
            msg = dataBizService.getFileByFloder(funcId, map.get("DATAFORMAT"), map.get("DATAPART"), paras, uc, json);
        } catch (Exception e) {
            msg = dataBizService.getDataEx(map, json, uc, methodName, e, "获取文件出现异常");
        }
        return msg;

    }

}
